package com.wande.dataplatform.service.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.wande.common.core.exception.ServiceException;
import com.wande.common.mybatis.core.page.PageQuery;
import com.wande.common.mybatis.core.page.TableDataInfo;
import com.wande.common.satoken.utils.LoginHelper;
import com.wande.dataplatform.domain.AssetCategory;
import com.wande.dataplatform.domain.DataAsset;
import com.wande.dataplatform.domain.dto.DataAssetDTO;
import com.wande.dataplatform.domain.vo.DataAssetStatisticsVO;
import com.wande.dataplatform.mapper.AssetCategoryMapper;
import com.wande.dataplatform.mapper.DataAssetMapper;
import com.wande.dataplatform.service.IDataAssetService;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.time.LocalDateTime;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * 数据资产Service业务层处理
 *
 * @author ruoyi
 */
@Slf4j
@RequiredArgsConstructor
@Service
public class DataAssetServiceImpl implements IDataAssetService {

    private final DataAssetMapper baseMapper;
    private final AssetCategoryMapper categoryMapper;

    /**
     * 查询数据资产
     */
    @Override
    public DataAssetDTO queryById(Long id) {
        DataAsset asset = baseMapper.selectById(id);
        if (asset == null) {
            throw new ServiceException("数据资产不存在");
        }
        DataAssetDTO dto = BeanUtil.copyProperties(asset, DataAssetDTO.class);
        
        // 查询分类名称
        if (asset.getCategoryId() != null) {
            AssetCategory category = categoryMapper.selectById(asset.getCategoryId());
            if (category != null) {
                dto.setCategoryName(category.getName());
            }
        }
        
        return dto;
    }

    /**
     * 查询数据资产列表
     */
    @Override
    public TableDataInfo<DataAssetDTO> queryPageList(DataAssetDTO dto, PageQuery pageQuery) {
        LambdaQueryWrapper<DataAsset> lqw = buildQueryWrapper(dto);
        Page<DataAsset> page = baseMapper.selectPage(pageQuery.build(), lqw);
        
        // 创建结果Page对象
        Page<DataAssetDTO> resultPage = new Page<>(page.getCurrent(), page.getSize(), page.getTotal());
        
        List<DataAssetDTO> dtoList = page.getRecords().stream()
            .map(asset -> {
                DataAssetDTO assetDTO = BeanUtil.copyProperties(asset, DataAssetDTO.class);
                // 查询分类名称
                if (asset.getCategoryId() != null) {
                    AssetCategory category = categoryMapper.selectById(asset.getCategoryId());
                    if (category != null) {
                        assetDTO.setCategoryName(category.getName());
                    }
                }
                return assetDTO;
            })
            .collect(Collectors.toList());
        
        resultPage.setRecords(dtoList);
        return TableDataInfo.build(resultPage);
    }

    /**
     * 查询数据资产列表
     */
    @Override
    public List<DataAssetDTO> queryList(DataAssetDTO dto) {
        LambdaQueryWrapper<DataAsset> lqw = buildQueryWrapper(dto);
        List<DataAsset> list = baseMapper.selectList(lqw);
        
        return list.stream()
            .map(asset -> {
                DataAssetDTO assetDTO = BeanUtil.copyProperties(asset, DataAssetDTO.class);
                // 查询分类名称
                if (asset.getCategoryId() != null) {
                    AssetCategory category = categoryMapper.selectById(asset.getCategoryId());
                    if (category != null) {
                        assetDTO.setCategoryName(category.getName());
                    }
                }
                return assetDTO;
            })
            .collect(Collectors.toList());
    }

    /**
     * 构建查询条件
     */
    private LambdaQueryWrapper<DataAsset> buildQueryWrapper(DataAssetDTO dto) {
        LambdaQueryWrapper<DataAsset> lqw = Wrappers.lambdaQuery();
        lqw.like(StrUtil.isNotBlank(dto.getName()), DataAsset::getName, dto.getName());
        lqw.eq(StrUtil.isNotBlank(dto.getAssetType()), DataAsset::getAssetType, dto.getAssetType());
        lqw.eq(dto.getCategoryId() != null, DataAsset::getCategoryId, dto.getCategoryId());
        lqw.eq(StrUtil.isNotBlank(dto.getLevel()), DataAsset::getLevel, dto.getLevel());
        lqw.eq(StrUtil.isNotBlank(dto.getStatus()), DataAsset::getStatus, dto.getStatus());
        lqw.eq(dto.getProjectId() != null, DataAsset::getProjectId, dto.getProjectId());
        lqw.orderByDesc(DataAsset::getCreateTime);
        return lqw;
    }

    /**
     * 新增数据资产
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public Long insertDataAsset(DataAssetDTO dto) {
        DataAsset asset = BeanUtil.copyProperties(dto, DataAsset.class);
        
        // 设置创建人信息
        try {
            Long userId = LoginHelper.getUserId();
            String username = LoginHelper.getUsername();
            asset.setCreatorId(userId);
            asset.setCreatorName(username);
        } catch (Exception e) {
            log.warn("获取当前用户信息失败", e);
        }
        
        // 初始化使用次数
        if (asset.getUseCount() == null) {
            asset.setUseCount(0);
        }
        
        // 默认状态为草稿
        if (StrUtil.isBlank(asset.getStatus())) {
            asset.setStatus("DRAFT");
        }
        
        baseMapper.insert(asset);
        return asset.getId();
    }

    /**
     * 修改数据资产
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public Boolean updateDataAsset(DataAssetDTO dto) {
        DataAsset asset = baseMapper.selectById(dto.getId());
        if (asset == null) {
            throw new ServiceException("数据资产不存在");
        }
        
        BeanUtil.copyProperties(dto, asset, "id", "creatorId", "creatorName", "createTime", "useCount", "lastUseTime");
        
        // 设置更新人信息
        try {
            Long userId = LoginHelper.getUserId();
            String username = LoginHelper.getUsername();
            asset.setUpdaterId(userId);
            asset.setUpdaterName(username);
        } catch (Exception e) {
            log.warn("获取当前用户信息失败", e);
        }
        
        return baseMapper.updateById(asset) > 0;
    }

    /**
     * 批量删除数据资产
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public Boolean deleteByIds(List<Long> ids) {
        return baseMapper.deleteBatchIds(ids) > 0;
    }

    /**
     * 删除数据资产信息
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public Boolean deleteById(Long id) {
        return baseMapper.deleteById(id) > 0;
    }

    /**
     * 更新资产状态
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public Boolean updateStatus(Long id, String status) {
        DataAsset asset = baseMapper.selectById(id);
        if (asset == null) {
            throw new ServiceException("数据资产不存在");
        }
        
        asset.setStatus(status);
        
        // 设置更新人信息
        try {
            Long userId = LoginHelper.getUserId();
            String username = LoginHelper.getUsername();
            asset.setUpdaterId(userId);
            asset.setUpdaterName(username);
        } catch (Exception e) {
            log.warn("获取当前用户信息失败", e);
        }
        
        return baseMapper.updateById(asset) > 0;
    }

    /**
     * 增加使用次数
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public Boolean incrementUseCount(Long id) {
        DataAsset asset = baseMapper.selectById(id);
        if (asset == null) {
            throw new ServiceException("数据资产不存在");
        }
        
        asset.setUseCount(asset.getUseCount() + 1);
        asset.setLastUseTime(LocalDateTime.now());
        
        return baseMapper.updateById(asset) > 0;
    }

    /**
     * 搜索数据资产
     */
    @Override
    public TableDataInfo<DataAssetDTO> searchAssets(String keyword, PageQuery pageQuery) {
        LambdaQueryWrapper<DataAsset> lqw = Wrappers.lambdaQuery();
        lqw.and(wrapper -> wrapper
            .like(DataAsset::getName, keyword)
            .or()
            .like(DataAsset::getDescription, keyword)
            .or()
            .like(DataAsset::getTags, keyword)
        );
        lqw.orderByDesc(DataAsset::getUseCount, DataAsset::getCreateTime);
        
        Page<DataAsset> page = baseMapper.selectPage(pageQuery.build(), lqw);
        
        // 创建结果Page对象
        Page<DataAssetDTO> resultPage = new Page<>(page.getCurrent(), page.getSize(), page.getTotal());
        
        List<DataAssetDTO> dtoList = page.getRecords().stream()
            .map(asset -> {
                DataAssetDTO assetDTO = BeanUtil.copyProperties(asset, DataAssetDTO.class);
                // 查询分类名称
                if (asset.getCategoryId() != null) {
                    AssetCategory category = categoryMapper.selectById(asset.getCategoryId());
                    if (category != null) {
                        assetDTO.setCategoryName(category.getName());
                    }
                }
                return assetDTO;
            })
            .collect(Collectors.toList());
        
        resultPage.setRecords(dtoList);
        return TableDataInfo.build(resultPage);
    }

    /**
     * 获取资产使用统计
     */
    @Override
    public DataAssetStatisticsVO getStatistics(Long projectId) {
        DataAssetStatisticsVO vo = new DataAssetStatisticsVO();
        
        LambdaQueryWrapper<DataAsset> lqw = Wrappers.lambdaQuery();
        if (projectId != null) {
            lqw.eq(DataAsset::getProjectId, projectId);
        }
        
        // 总数
        vo.setTotalCount(Math.toIntExact(baseMapper.selectCount(lqw)));
        
        // 按状态统计
        vo.setPublishedCount(Math.toIntExact(baseMapper.selectCount(
            Wrappers.lambdaQuery(DataAsset.class)
                .eq(projectId != null, DataAsset::getProjectId, projectId)
                .eq(DataAsset::getStatus, "PUBLISHED")
        )));
        
        vo.setDraftCount(Math.toIntExact(baseMapper.selectCount(
            Wrappers.lambdaQuery(DataAsset.class)
                .eq(projectId != null, DataAsset::getProjectId, projectId)
                .eq(DataAsset::getStatus, "DRAFT")
        )));
        
        vo.setArchivedCount(Math.toIntExact(baseMapper.selectCount(
            Wrappers.lambdaQuery(DataAsset.class)
                .eq(projectId != null, DataAsset::getProjectId, projectId)
                .eq(DataAsset::getStatus, "ARCHIVED")
        )));
        
        // 按类型统计
        vo.setTypeCount(countByType(projectId));
        
        // 按分级统计
        vo.setLevelCount(countByLevel(projectId));
        
        // 按分类统计
        vo.setCategoryCount(countByCategory(projectId));
        
        // 最近使用的资产数（最近7天）
        vo.setRecentlyUsedCount(Math.toIntExact(baseMapper.selectCount(
            Wrappers.lambdaQuery(DataAsset.class)
                .eq(projectId != null, DataAsset::getProjectId, projectId)
                .ge(DataAsset::getLastUseTime, LocalDateTime.now().minusDays(7))
        )));
        
        return vo;
    }

    /**
     * 按分类统计资产数量
     */
    @Override
    public Map<String, Integer> countByCategory(Long projectId) {
        LambdaQueryWrapper<DataAsset> lqw = Wrappers.lambdaQuery();
        if (projectId != null) {
            lqw.eq(DataAsset::getProjectId, projectId);
        }
        
        List<DataAsset> assets = baseMapper.selectList(lqw);
        Map<String, Integer> categoryCount = new HashMap<>();
        
        for (DataAsset asset : assets) {
            if (asset.getCategoryId() != null) {
                AssetCategory category = categoryMapper.selectById(asset.getCategoryId());
                if (category != null) {
                    String categoryName = category.getName();
                    categoryCount.put(categoryName, categoryCount.getOrDefault(categoryName, 0) + 1);
                }
            } else {
                categoryCount.put("未分类", categoryCount.getOrDefault("未分类", 0) + 1);
            }
        }
        
        return categoryCount;
    }

    /**
     * 按类型统计资产数量
     */
    @Override
    public Map<String, Integer> countByType(Long projectId) {
        LambdaQueryWrapper<DataAsset> lqw = Wrappers.lambdaQuery();
        if (projectId != null) {
            lqw.eq(DataAsset::getProjectId, projectId);
        }
        
        List<DataAsset> assets = baseMapper.selectList(lqw);
        Map<String, Integer> typeCount = new HashMap<>();
        
        for (DataAsset asset : assets) {
            String type = asset.getAssetType();
            typeCount.put(type, typeCount.getOrDefault(type, 0) + 1);
        }
        
        return typeCount;
    }

    /**
     * 按分级统计资产数量
     */
    @Override
    public Map<String, Integer> countByLevel(Long projectId) {
        LambdaQueryWrapper<DataAsset> lqw = Wrappers.lambdaQuery();
        if (projectId != null) {
            lqw.eq(DataAsset::getProjectId, projectId);
        }
        
        List<DataAsset> assets = baseMapper.selectList(lqw);
        Map<String, Integer> levelCount = new HashMap<>();
        
        for (DataAsset asset : assets) {
            String level = asset.getLevel();
            if (StrUtil.isNotBlank(level)) {
                levelCount.put(level, levelCount.getOrDefault(level, 0) + 1);
            }
        }
        
        return levelCount;
    }

}
